package pfq.demo.okhttp;

import android.util.Log;

import org.jetbrains.annotations.NotNull;

import java.io.IOException;

import okhttp3.Interceptor;
import okhttp3.Request;
import okhttp3.Response;

/**
 * 有家公司三面的面试官问了一个问题：在网络请求的时候，如果默认的URL返回失败，则自动切换到新URL，这个如何做？
 * <p>
 * 当时我没回答上来，这个其实很简单，只要自定义一个OkHttp的拦截器即可：
 * 1. 执行默认URL的请求并获取Response
 * 2. 判断Response中的code是否不为200
 * 3. 如果不为200，则切换到新URL，重新发起请求
 * <p>
 * 为什么没回答上来？是因为对OkHttp的拦截器不了解，只知道有拦截器，以为有请求拦截器和返回拦截器，分别对请求和返回进行修改，
 * 所以就根本没往拦截器上想。
 * <p>
 * 但其实不是这样的，自定义的拦截器分为应用拦截器和网络拦截器，区别是两者调用的时机不同，应用拦截器在所有拦截器中优先执行，而网络拦截器是在发起网络前执行，
 * 在网络拦截器执行之前还会执行几个OkHttp自带的拦截器，比如RetryAndFollowUpInterceptor这个是重试和重定向拦截器，如果发生重定向，则网络拦截器会被调用两次，而应用拦截器只会被调用一次，这就是两者的区别。
 * <p>
 * 另外，在拦截器中，可以获取Request和Response，而不是只能对Request或者Response做修改，这样也就是解决了面试官提出的切换URL的问题了。
 */
public class SwitchURLInterceptor implements Interceptor {
    final String NEW_URL = "https://wanandroid.com/wxarticle/list/408/1/json";

    @NotNull
    @Override
    public Response intercept(@NotNull Chain chain) throws IOException {

        Response response = chain.proceed(chain.request());

        Log.d("pangfq", "SwitchURLInterceptor: " + response.code());

        if (response.code() != 200) {
            response.close();
            // 切换到新URL
            Request newRequest = chain.request().newBuilder().url(NEW_URL).build();
            // 重新发起请求
            response = chain.proceed(newRequest);
        }

        return response;
    }
}
